package com.itheima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.article.feign.ApAuthorFeign;
import com.itheima.article.pojo.ApAuthor;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.vo.PageResultVo;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.ApUserRealnamePageRequestDto;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.pojo.ApUserRealname;
import com.itheima.user.mapper.ApUserRealnameMapper;
import com.itheima.user.service.ApUserRealnameService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.wemedia.feign.WmUserfeign;
import com.itheima.wemedia.pojo.WmUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @description <p>APP实名认证信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Service
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {

    @Resource
    private ApUserMapper apUserMapper;

    @Resource
    private WmUserfeign wmUserfeign;

    @Resource
    private ApAuthorFeign apAuthorFeign;

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResultVo findPage(ApUserRealnamePageRequestDto dto) {
        //1. 分页参数设置
        IPage<ApUserRealname> pageInfo=new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<ApUserRealname> queryWrapper=new LambdaQueryWrapper<>();
        //2. 构建查询条件
        queryWrapper.eq(!StringUtils.isEmpty(dto.getStatus()),ApUserRealname::getStatus,dto.getStatus());
        //3. 执行查询
        page(pageInfo,queryWrapper);
        //4. 分页结果封装并返回
        return PageResultVo.pageResult(dto.getPage(),dto.getSize(),pageInfo.getTotal(),pageInfo.getRecords());
    }

    /**
     * 实名认证 - 审核通过
     * @param paramMap
     */
    @Override
    @Transactional
    public void authPass(Map<String, Object> paramMap) {
        //0.获取参数,并非空校验
        Integer id = (Integer) paramMap.get("id");//实名认证id
        if (StringUtils.isEmpty(id)){
            throw  new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        //1.更新实名认证申请记录表的状态
        //1.1根据id查询实名认证记录，获取用户user_id
        ApUserRealname apUserRealname = getById(id);
        Long apUserId = apUserRealname.getUserId();
        //1.2更新实名认证申请记录表的状态
        updateApUserRealnameStatus(id);
        //2.更新app用户的认证状态与flag的值
        //2.1构建updatePojo，设置 认证状态为1，设置flag=1
        updateApUserAuthenticationAndFlag(apUserId);
        //2.2更新
        //TODO
        //3.添加自媒体账号
        WmUser wmUser = addWmUser(apUserId);
        //4.添加作者账号
        addApAuthor(apUserId,wmUser);
    }

    /**
     * 实名认证 - 审核驳回
     *
     * @param paramMap
     * @return
     */
    @Override
    public void authFail(Map<String, Object> paramMap) {
        //0.获取参数,并非空校验
        Integer id = (Integer) paramMap.get("id");//实名认证id
        if (StringUtils.isEmpty(id)){
            throw  new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        //2.构建更新pojo
        ApUserRealname apUserRealnameUpdatePojo = new ApUserRealname();
        //3.给要更新的字段属性设置值
        //最后的更新时间
        apUserRealnameUpdatePojo.setUpdatedTime(LocalDateTime.now());
        //状态改为失败 驳回
        apUserRealnameUpdatePojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_REJECT);
        apUserRealnameUpdatePojo.setId(id.longValue());
        //设置驳回的原因
        apUserRealnameUpdatePojo.setReason(((String) paramMap.get("msg")));
        //4.执行更新
        updateById(apUserRealnameUpdatePojo);
    }

    /**
     * 添加作者
     */
    private void addApAuthor(Long apUserId,WmUser wmUser) {
        //通过apUserId与自媒体账号id查询作者是否存在
        ResultVo<ApAuthor> getResult = apAuthorFeign.getByApUserIdWmUserId(apUserId, wmUser.getId());
        //解析查询结果
        if (!getResult.isSuccess()) {
            //远程调用，失败报错
            //远程调用失败：超时、异常、熔断了
            log.error("远程调用文章微服务查询作者账号失败了！:"+getResult.getErrorMessage());
            throw new LeadNewsException("实名认证失败了！:"+getResult.getErrorMessage());
        }
        //没报错，则获取作者信息
        ApAuthor author = getResult.getData();
        //判断作者是否为空
        if (null==author) {
            //为空则作者账号不存在，则添加作者账号
            author = new ApAuthor();
            //创建作者对象，给对象属性赋值
            author.setCreatedTime(LocalDateTime.now());
            author.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
            author.setUserId(apUserId);
            author.setWmUserId(wmUser.getId());
            author.setName(wmUser.getName());
            //远程调用文章微服务添加作者账号
            ResultVo addResult = apAuthorFeign.addApAuthor(author);
            //解析结果
            if (!addResult.isSuccess()){
                //远程调用失败：超时、异常、熔断了
                log.error("远程调用文章微服务添加作者账号失败了！:"+addResult.getErrorMessage());
                throw new LeadNewsException("实名认证失败了！:"+addResult.getErrorMessage());
            }
        }
    }

    /**
     * 添加自媒体人
     */
    private WmUser addWmUser(Long apUserId) {
        //1.先判断自媒体账号是否存在
        //1.1远程调用，通过apUserId查询自媒体用户表(wm_user在自媒体微服务)
        ResultVo<WmUser> wmUserResultVo = wmUserfeign.getByApUserId(apUserId);
        //解析远程调用的结果
        if (!wmUserResultVo.isSuccess()){
            //远程调用失败：超时、异常、熔断了
            log.error("远程调用自媒体失败了！:"+wmUserResultVo.getErrorMessage());
            throw new LeadNewsException("实名认证失败了！:"+wmUserResultVo.getErrorMessage());
        }
        WmUser wmUser = wmUserResultVo.getData();
        //2.如果不存在则添加自媒体人
        if (StringUtils.isEmpty(wmUser)) {
            //创建WmUser对象，并且赋值
            wmUser = new WmUser();
            //查询apUser的用户信息
            ApUser apUser = apUserMapper.selectById(apUserId);
            //赋值属性
            BeanUtils.copyProperties(apUser, wmUser);
            wmUser.setId(null);
            wmUser.setNickname(apUser.getName());
            wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_OK);
            //个人媒体
            wmUser.setType(BusinessConstants.WmUserConstants.TYPE_PERSONAL);
            wmUser.setScore(0);//经营所得分数
            wmUser.setCreatedTime(LocalDateTime.now());
            //用户id
            wmUser.setApUserId(apUserId);
            //远程调用添加自媒体账号
            ResultVo<WmUser> addResult = wmUserfeign.add(wmUser);
            if (!addResult.isSuccess()) {
                log.error("远程调用自媒体添加账号失败了！:" + addResult.getErrorMessage());
                throw new LeadNewsException("实名认证失败了！:" + addResult.getErrorMessage());
            }
            //新添加的自媒体账号
            wmUser = addResult.getData();
        }
        //存在 返回自媒体账号
        return wmUser;
    }

    /**
     * 更新用户认证状态与flag的值
     * @param apUserId
     */
    private void updateApUserAuthenticationAndFlag(Long apUserId) {
        //2.更新app用户的认证状态与flag的值
        //2.1构建updatePojo，设置 认证状态为1，设置flag=1
        ApUser updatePojo = new ApUser();
        updatePojo.setFlag(BusinessConstants.ApUserConstants.FLAG_WEMEDIA);
        updatePojo.setIsIdentityAuthentication(BusinessConstants.ApUserConstants.AUTHENTICATED);
        updatePojo.setId(apUserId);
        //2.2更新
        apUserMapper.updateById(updatePojo);
    }

    /**
     * 更新实名认证记录的状态
     * @param id
     */
    private void updateApUserRealnameStatus(Integer id) {
        ApUserRealname apUserRealnameUpdatePojo = new ApUserRealname();
        //最后的更新时间
        apUserRealnameUpdatePojo.setUpdatedTime(LocalDateTime.now());
        //状态改为审核通过
        apUserRealnameUpdatePojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_PASS);
        apUserRealnameUpdatePojo.setId(id.longValue());
        updateById(apUserRealnameUpdatePojo);
    }
}
